﻿/*
 * *******************************************************
 *
 * 作者：HZY
 *
 * 开源地址：https://gitee.com/hzy6
 *
 * *******************************************************
 */

namespace HZY.Framework.Core.Utils;

/// <summary>
/// 对象操作工具
/// </summary>
public static class ObjectUtil
{
    /// <summary>
    /// int
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static int ToInt32<T>(this T value)
    {
        if (value == null) return 0;

        try
        {
            var val = value.ToStr();

            if (val?.Count(w => w == '.') == 1)
            {
                // 去掉小数点 之后的字符
                val = val[..val.IndexOf('.')];
            }

            return Convert.ToInt32(val);
        }
        catch (Exception)
        {
            Int32.TryParse(value.ToStr(), out int result);
            return result;
        }
    }

    /// <summary>
    /// long
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static long ToLong<T>(this T value)
    {
        if (value == null) return 0L;

        try
        {
            var val = value.ToStr();

            if (val?.Count(w => w == '.') == 1)
            {
                // 去掉小数点 之后的字符
                val = val[..val.IndexOf('.')];
            }

            return Convert.ToInt64(val);
        }
        catch (Exception)
        {
            Int64.TryParse(value.ToStr(), out long result);
            return result;
        }
    }

    /// <summary>
    /// float
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static float ToFloat<T>(this T value)
    {
        if (value == null) return 0;

        return float.TryParse(value.ToStr(), out var result) ? result : 0;
    }

    /// <summary>
    /// double
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static double ToDouble<T>(this T value)
    {
        if (value == null) return 0;

        return double.TryParse(value.ToStr(), out var result) ? result : 0;
    }

    /// <summary>
    /// decimal
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static decimal ToDecimal<T>(this T value)
    {
        if (value == null) return 0;

        return decimal.TryParse(value.ToStr(), out var result) ? result : 0;
    }

    /// <summary>
    /// Guid
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static Guid ToGuid<T>(this T value)
    {
        if (value == null) return Guid.Empty;

        return Guid.TryParse(value.ToStr(), out var result) ? result : Guid.Empty;
    }

    /// <summary>
    /// Guid?
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static Guid? ToGuidNull<T>(this T value)
    {
        if (value == null) return null;

        return Guid.TryParse(value.ToStr(), out var result) ? (Guid?)result : null;
    }

    /// <summary>
    /// GuidString
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static string? ToGuidStr<T>(this T value) => value.ToGuid().ToStr();

    /// <summary>
    /// bool
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static bool ToBool<T>(this T value)
    {
        if (value == null) return false;

        return bool.TryParse(value.ToStr(), out var result) && result;
    }

    /// <summary>
    /// byte[]
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static byte[]? ToBytes<T>(this T value) => value == null ? null : value as byte[];

    /// <summary>
    /// 是否为空
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static bool IsNullOrEmpty(this string input)
    {
        if (input == null) return true;
        return string.IsNullOrEmpty(input);
    }

    /// <summary>
    /// 是否为空
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static bool IsNullOrWhiteSpace(this string input)
    {
        if (input == null) return true;
        return string.IsNullOrWhiteSpace(input);
    }


    /// <summary>
    /// 通过类型获取实例
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static T? CreateInstance<T>() where T : class, new()
    {
        var t = typeof(T);
        if (t.IsValueType || typeof(T) == typeof(string))
            return default;
        return (T?)Activator.CreateInstance(t);
    }

    /// <summary>
    /// 将 Null 对象转换为 对象的实例
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="model"></param>
    /// <param name="defaultInstance">自定义 默认实例</param>
    /// <returns></returns>
    public static T? NullSafe<T>(this T model, T? defaultInstance = null) where T : class, new()
    {
        if (model != null) return model;
        return defaultInstance ?? CreateInstance<T>();
    }


}
